package com.sproutcat.sample;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.cache.Cache;
import org.springframework.cache.annotation.ProxyCachingConfiguration;
import org.springframework.cache.interceptor.CacheInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;

import java.time.Duration;

/**
 * 缓存代理驱动启动配置
 *
 * @author tzg
 */
@Slf4j
public class CustomRedisCacheManager extends RedisCacheManager {

    private final RedisCacheWriter cacheWriter;
    private final RedisCacheConfiguration defaultCacheConfig;

    public CustomRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration cacheConfiguration) {
        super(cacheWriter, cacheConfiguration);
        this.cacheWriter = cacheWriter;
        this.defaultCacheConfig = cacheConfiguration;
    }

    @Autowired
    DefaultListableBeanFactory beanFactory;

    @Override
    public Cache getCache(String name) {
        if (StringUtils.isEmpty(name)) {
            return super.getCache(name);
        }
        String[] array = StringUtils.delimitedListToStringArray(name, "#");
        Cache cache = super.getCache(array[0]);
        if (cache instanceof CustomRedisCache) {
            if (array.length > 1) {
                String value = array[1];
                if (value.contains("$")) {
                    value = beanFactory.resolveEmbeddedValue(value);
                }
                // 解析TTL
                long ttl = Long.parseLong(value);
                ((CustomRedisCache) cache).setTtl(Duration.ofSeconds(ttl));
            } else {
                ((CustomRedisCache) cache).setTtl(null);
            }
        }
        return cache;
    }

    @Override
    protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {
        return new CustomRedisCache(name, cacheWriter, cacheConfig != null ? cacheConfig : defaultCacheConfig);
    }

}
